/*
 * mainwindow.h
 * 串口调试工具 - 主窗口头文件
 * 
 * 说明：本头文件包含MainWindow类的核心声明，负责界面交互和各模块的协调。
 * 功能模块被拆分为：
 * - serial_manager.h/cpp: 串口配置和管理相关功能
 * - data_io.h/cpp: 数据收发和格式化相关功能
 * - utils.h/cpp: 通用工具函数
 * - settings_manager.h/cpp: 设置管理功能
 */

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>   // 基类，提供主窗口功能
#include <QSerialPort>   // 串口类，用于串口通信
#include <QTimer>        // 定时器类，用于实现自动发送功能
#include <QPushButton>   // 按钮类

// 包含模块头文件
#include "serial_manager.h"
#include "data_io.h"
#include "utils.h"
#include "settings_manager.h"

// 前向声明UI命名空间中的MainWindow类
namespace Ui {
class MainWindow;
}

/**
 * @brief 主窗口类，继承自QMainWindow
 * 
 * 负责整个串口调试工具的用户界面和功能实现，包括串口连接、
 * 数据收发、参数配置等功能。
 */
class MainWindow : public QMainWindow
{
    Q_OBJECT  // Qt元对象宏，启用信号槽机制

private:
    // 核心模块实例
    SerialManager *serialManager;  // 串口管理器实例
    DataIO *dataIO;                // 数据IO管理器实例
    SettingsManager *settingsManager; // 设置管理器实例
    
    // UI和核心对象
    Ui::MainWindow *ui;           // UI界面指针
    QSerialPort *serialPort;      // 串口对象指针（由SerialManager管理）
    QTimer *autoSendTimer;        // 自动发送定时器
    QTimer *portCheckTimer;       // 串口检测定时器
    QTimer *receiveFlushTimer;    // 接收区批量刷新定时器
    QTimer statsUpdateTimer;      // 状态栏统计更新定时器
    
public:
    /**
     * @brief 构造函数
     * @param parent 父窗口指针
     */
    explicit MainWindow(QWidget *parent = nullptr);
    
    /**
     * @brief 析构函数
     * 
     * 清理应用程序使用的所有资源，包括删除UI对象、关闭并删除串口对象、
     * 删除定时器对象等，确保没有内存泄漏。
     */
    ~MainWindow();

protected:
    /**
     * @brief 事件过滤器函数，重写QObject类的虚函数
     * @param obj 被监视的对象
     * @param event 发生的事件
     * @return 是否处理了事件
     */
    bool eventFilter(QObject *obj, QEvent *event) override;
    
    /**
     * @brief 处理关闭事件
     * @param event 关闭事件对象
     * 
     * 当窗口即将关闭时调用，执行必要的清理工作
     */
    void closeEvent(QCloseEvent* event) override;
    
    /**
     * @brief 窗口大小变化事件处理函数
     * @param event 窗口大小变化事件
     * 
     * 当窗口大小发生变化时重新格式化显示接收的数据，实现文本自动重排。
     */
    void resizeEvent(QResizeEvent *event) override;

private slots:
    // 串口控制相关槽函数（实现位于mainwindow_serial.cpp）
    
    // 定时检测串口可用性
    void checkSerialPortsAvailability();
    /**
     * @brief 连接/断开串口按钮点击事件槽
     *
     * 根据当前连接状态执行连接或断开操作：
     * - 连接时读取并校验串口配置（端口、波特率、数据位、停止位、校验、流控），尝试打开串口。
     * - 断开时关闭串口并恢复可编辑的UI控件状态。
     */
    void on_connectButton_clicked();
    
    // 参数设置按钮点击事件槽（自动通过Qt的connectSlotsByName机制连接）
    void on_advancedSettingsButton_clicked();
    /**
     * @brief 串口下拉框选项变更事件槽
     * @param index 当前选中的选项索引
     * 
     * 当用户从串口下拉列表中选择不同的串口设备时被调用。该函数负责：
     * 1. 从选中项中提取有效的串口名称
     * 2. 应用该串口的历史波特率设置（如果存在）
     * 3. 检测选中串口的状态（是否被占用）
     * 4. 根据串口状态更新连接按钮的可用状态
     */
    void on_serialPortComboBox_currentIndexChanged(int index);
    
    /**
     * @brief 更新连接状态
     * @param connected 是否已连接；true表示建立连接，false表示断开连接。
     *
     * 切换UI控件的启用状态、更新连接按钮文本、维护当前连接串口名及最近历史；
     * 在断开时关闭串口并重新填充串口列表以刷新状态标识。
     */
    void updateConnectionStatus(bool connected);
    
    // 数据收发相关槽函数（实现位于mainwindow_io.cpp）
    /**
     * @brief 发送数据按钮点击事件槽
     *
     * 从发送文本框读取内容，依据发送格式（ASCII/HEX）解析为字节数组，
     * 并调用发送方法写入串口。
     */
    void on_sendButton_clicked();
    
    /**
     * @brief 清空接收区按钮点击事件槽
     *
     * 清除接收文本框中的所有显示内容，不影响串口连接状态和配置。
     */
    void on_clearReceiveButton_clicked();
    
    /**
     * @brief 清空发送区按钮点击事件槽
     *
     * 清除发送文本框中的所有内容，不触发实际的发送操作或格式转换。
     */
    void on_clearSendButton_clicked();
    
    /**
     * @brief 刷新串口列表按钮点击事件槽
     *
     * 重新扫描系统可用串口并更新下拉列表；
     * 保留并标注当前程序已连接的串口为"[已连接]"，他程序占用的为"[已占用]"。
     */
    void on_refreshButton_clicked();
    
    /**
     * @brief 自动发送定时器超时事件槽
     *
     * 在已连接且发送文本框非空的情况下，触发一次发送操作。
     */
    void on_autoSendTimer_timeout();
    
    /**
     * @brief 读取串口数据事件槽
     *
     * 从串口缓冲区读取所有可用数据，根据接收格式（ASCII/HEX）格式化后追加到接收文本框。
     */
    void readSerialData();

    // 接收缓冲批量刷新定时器槽
    void on_receiveFlushTimer_timeout();
    
    /**
     * @brief 十六进制发送复选框状态变更事件槽
     * @param arg1 复选框状态，Qt::Checked表示启用十六进制发送
     */
    void on_hexSendCheckBox_stateChanged(int arg1);
    
    /**
     * @brief 十六进制接收复选框状态变更事件槽
     * @param arg1 复选框状态，Qt::Checked表示启用十六进制接收
     */
    void on_hexReceiveCheckBox_stateChanged(int arg1);
    
    /**
     * @brief 自动发送复选框状态变更事件槽
     * @param arg1 复选框状态，Qt::Checked表示启用自动发送
     */
    void on_autoSendCheckBox_stateChanged(int arg1);
    
    /**
     * @brief 自动发送间隔值变更事件槽
     * @param arg1 新的时间间隔值，单位为毫秒
     */
    void on_autoSendIntervalSpinBox_valueChanged(int arg1);
    
    /**
     * @brief 清空统计信息按钮点击事件槽
     */
    void on_clearStatsButton_clicked();
    
        // 时间戳和自动滚动功能现在通过按钮的toggled信号和lambda表达式处理
    void clearReceiveStats();

    
    /**
     * @brief 显示状态栏消息
     * @param message 要显示的消息内容
     * 
     * 在状态栏显示指定的消息，用于用户交互反馈。
     */
    void showStatusMessage(const QString &message);
    
    /**
     * @brief 显示串口连接对话框
     * @return bool 是否成功连接串口
     * 
     * 显示串口选择和配置对话框，允许用户选择是否连接串口
     */
    bool showSerialConnectionDialog();
    
    /**
     * @brief 转换输入格式
     * 
     * 当切换ASCII/Hex模式时，自动将当前输入区域的内容转换为对应的格式。
     * 保持光标位置相对不变，确保用户体验连续性。
     */

private:
    // 状态标志
    bool isConnected;             // 连接状态标志
    bool isHexSend;               // 十六进制发送标志
    bool isHexReceive;            // 十六进制接收标志
    bool isAutoSend;              // 自动发送标志
    bool isTimestampEnabled;      // 时间戳显示标志
    bool isAutoScrollEnabled;     // 自动滚动到最新数据标志
    bool errorMessageBoxActive;   // 错误消息框是否正在显示
    bool pauseReceiving;          // 暂停接收到UI（仍读取以避免串口缓冲积压）
    
    // UI相关成员
    QPushButton* statusClearStatsButton; // 状态栏清除统计按钮
    
    // 接收缓冲区设置
    int maxRetainedLines; // 接收区域最大保留行数
    
    // 辅助方法
    void enforceMaxLines(); // 强制限制接收区域行数
    void updatePortList();  // 更新串口列表
    void initializeUI(); // 初始化用户界面
    void connectSignalsSlots(); // 连接信号和槽
    void onDataReceived(const QByteArray &data); // 处理接收到的数据
    void sendData(); // 发送数据
    void appendToReceiveArea(const QString &text); // 追加文本到接收区域
    void onConnectionStatusChanged(bool connected); // 连接状态变化处理
    void updateUIConnectionState(); // 更新UI连接状态
    void populatePortList(); // 填充串口列表
    void reformatAndRedisplayData(); // 重新格式化并重显示数据
    void loadSettings(); // 加载设置
    void saveSettings(); // 保存设置
    void updateStatsStatusBar(); // 更新统计状态栏
    void validateSendInput(); // 验证发送输入
    void exportReceiveToFile(); // 导出接收内容到文件
    void findInReceive(const QString &text, bool highlightAll); // 在接收区域查找文本
    void convertInputFormat(); // 转换输入格式

    // 新增：端口支持的数据位预探测方法（用于在识别串口时预填充缓存）
    QStringList probeSupportedDataBits(const QString &portName);
};

#endif // MAINWINDOW_H